<?php
/**
 * Created by PhpStorm.
 * User: yandian
 * Date: 17/$span/10
 * Time: 11:55
 */

namespace app\common\util;


use ArrayAccess;
use think\Config;
use think\Response;

class Pager implements ArrayAccess
{
    private $curPage;
    private $total;
    private $pageSize;
    private $rows;
    private $startPage;
    private $endPage;
    private static $idPrefix = 0;

    public function __construct($curPage, $pageSize = 10)
    {
        self::$idPrefix++;
        $this->curPage = $curPage;
        $this->pageSize = $pageSize;
    }

    public function setTotal($total)
    {
        $this->total = $total;
    }


    public function display($span = 4, $warnEmpty = 0)
    {
        $pageCount = $this->getPageCount();
        $curPage = $this->curPage;
        if ($curPage > $pageCount) {
            $curPage = $pageCount;
        }
        $start = $curPage - $span;
        if ($start < 1) {
            $start = 1;
        }
        $end = $curPage + $span;
        if ($end > $pageCount) {
            $end = $pageCount;
        }

        if ($curPage - $start < $span) {
            $end += $span - ($curPage - $start);
            if ($end > $pageCount) {
                $end = $pageCount;
            }
        } else if ($end - $curPage < $span) {
            $start -= $span - ($end - $curPage);
            if ($start < 1) {
                $start = 1;
            }
        }
        $this->startPage = $start;
        $this->endPage = $end;
        $view = \think\View::instance(Config::get());
        $view->assign('pager', $this);
        $view->assign('warnEmpty', $warnEmpty);
        echo $view->fetch('widget/pager');
    }

    public function getTotal()
    {
        return $this->total;
    }

    public function setPageSize($pageSize)
    {
        $this->pageSize = $pageSize;
    }

    public function getPageSize()
    {
        return $this->pageSize;
    }

    public function getIdPrefix()
    {
        return 'id' . self::$idPrefix;
    }

    public function getStartPage()
    {
        return $this->startPage;
    }

    public function getEndPage()
    {
        return $this->endPage;
    }

    public function page($page)
    {
        static $params = null;
        if (is_null($params)) {
            $params = $_SERVER['REQUEST_URI'];
            if (($pos = strpos($params, 'p=')) > -1) {
                $params = substr($params, 0, $pos);
            }
            $lw = substr($params, -1);
            if ($lw != '?' && $lw != '&') {
                if (($pos = strpos($params, '?')) > -1) {
                    $params .= '&';
                } else {
                    $params .= '?';
                }
            }
            $params .= 'p=';
        }
        return $params . $page;
    }

    public function getPageCount()
    {
        static $rt = null;
        if ($rt === null) {
            $rt = intval(ceil($this->total / $this->pageSize));
        }
        return $rt;
    }

    public function getNextPage()
    {
        static $page = null;
        if ($page === null) {
            $pageCount = $this->getPageCount();
            $page = $this->curPage + 1;
            if ($page > $pageCount) {
                if ($page-1> $pageCount) {
                    Response::redirect($this->page($pageCount));
                    exit();
                }
                $page = $pageCount;
            }
            if ($page == $pageCount) {
                return null;
            }
        }
        return $page;
    }

    public function getPrevPage()
    {
        static $page = null;
        if ($page === null) {
            $page = $this->curPage - 1;
            if ($page < 1) {
                if($page < 0){
                    Response::redirect($this->page(1));
                    exit();
                }
                $page = 1;
            }
            if ($page == $this->curPage) {
                return null;
            }
        }
        return $page;
    }

    public function getCurPage()
    {
        return $this->curPage;
    }

    public function setRows($rows)
    {
        $this->rows = $rows;
    }

    public function getRows()
    {
        return $this->rows;
    }

    public function __get($name)
    {
        $m = 'get' . ucfirst($name);
        if (method_exists($this, $m)) {
            return $this->$m();
        }
        return null;
    }


    /**
     * Offset to retrieve
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
     * @param mixed $offset <p>
     * The offset to retrieve.
     * </p>
     * @return mixed Can return all value types.
     * @since 5.0.0
     */
    public function offsetGet($offset)
    {
        // TODO: Implement offsetGet() method.
        return $this->__get($offset);
    }

    /**
     * Offset to set
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
     * @param mixed $offset <p>
     * The offset to assign the value to.
     * </p>
     * @param mixed $value <p>
     * The value to set.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetSet($offset, $value)
    {
        // TODO: Implement offsetSet() method.
    }

    /**
     * Offset to unset
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
     * @param mixed $offset <p>
     * The offset to unset.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetUnset($offset)
    {
        // TODO: Implement offsetUnset() method.
    }

    /**
     * Whether a offset exists
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
     * @param mixed $offset <p>
     * An offset to check for.
     * </p>
     * @return boolean true on success or false on failure.
     * </p>
     * <p>
     * The return value will be casted to boolean if non-boolean was returned.
     * @since 5.0.0
     */
    public function offsetExists($offset)
    {
        // TODO: Implement offsetExists() method.
        return $this->__get($offset) != null;
    }
}